/* MIT License
 *
 * Copyright (c) 2012 Reuben Smith, Miami University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.droidlike.vsig;


import com.jme3.system.AppSettings;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;


/**
 * Entrance code for VSIG.
 *
 * @author smithre5
 */
public class VSIG
{
    /**
     * Entrance point for VSIG.
     *
     * @param args command-line arguments
     */
    public static void main(String[] args)
    {        
        try {
            // FIXD UI components appear behind canvas without this!
            JPopupMenu.setDefaultLightWeightPopupEnabled(false);

            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

            frame = new VSIGFrame();
            frame.setIconImages(new ArrayList<BufferedImage>(Arrays.asList(getIconImages())));
            frame.setVisible(true);
        }
        catch (Exception ex) {
            Logger.getLogger(VSIG.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    /**
     * Loads and returns 16x16, 32x32, and 128x128px icons for the application.
     *
     * @return an array of loaded icons
     */
    public static BufferedImage[] getIconImages()
    {
        BufferedImage[] icons = new BufferedImage[3];

        try {
            icons[0] = ImageIO.read(VSIG.class.getClassLoader().getResourceAsStream("Interface/icon16.png"));
            icons[1] = ImageIO.read(VSIG.class.getClassLoader().getResourceAsStream("Interface/icon32.png"));
            icons[2] = ImageIO.read(VSIG.class.getClassLoader().getResourceAsStream("Interface/icon128.png"));
        }
        catch (IOException ex) {
            Logger.getLogger(VSIG.class.getName()).log(Level.SEVERE, null, ex);
        }

        return icons;
    }
    
    
    public static boolean getDebugMode()
    {
        return debugMode;
    }
    
    
    public static boolean toggleDebugMode()
    {
        if (!VSIG.DEBUG) {
            return false;
        }
        
        return (debugMode = !debugMode);
    }


    /**
     * Creates and prepares a Simulation without starting it.
     *
     * @return the created Simulation
     */
    public static Simulation startSimulation(VSIGFrame frame)
    {
        AppSettings settings = new AppSettings(true);
        settings.setTitle(VSIG.TITLE);
        settings.setIcons(VSIG.getIconImages());

        sim = new Simulation(frame, Long.MIN_VALUE);
        sim.setSettings(settings);
        sim.setPauseOnLostFocus(true);
        sim.createCanvas();

        return sim;
    }


    /**
     * @return the current, active Simulation
     */
    public static Simulation getSimulation()
    {
        return sim;
    }


    /**
     * Stops the current Simulation and releases it.
     */
    public static void stopSimulation()
    {
        if (sim != null) {
            sim.getExecutorService().destroy();
            sim.stop(true);
            sim = null;
        }
    }


    /**
     * Sets the active profile. If the profile does not exist, it will attempt
     * to create it before assigning it as active. If no name is given, the
     * default profile will be loaded.
     * 
     * @param name the desired profile's name
     * @return true if successful; false otherwise
     */
    public static boolean setProfile(String name)
    {
        if (Util.isBlank(name)) {
            VSIG.profile = Profile.getDefault();
            frame.setTitle(VSIG.TITLE);
            
            return true;
        }
        
        Profile oldProfile = VSIG.profile;
        
        if ((VSIG.profile = Profile.load(name)) == null) {
            if ((VSIG.profile = Profile.create(name)) == null) {
                VSIG.profile = oldProfile;
                return false;
            }
        }
        
        frame.setTitle(VSIG.TITLE + " (" + name + ")");
        
        return true;
    }
    
    
    /**
     * @return the active profile
     */
    public static Profile getProfile()
    {
        return profile;
    }


    // Enables or disables debug-specific code.
    public static final boolean DEBUG = true;
    public static final String TITLE = "VSIG";
    public static final String COPYRIGHT = "Copyright © 2012 Reuben Smith, Miami University";
    public static final String[] CONTRIBUTORS = new String[]{};
    // Revision number.
    public static final short VERSION = 8;
    public static final String SERVICE_PATH = "bin/O2";
    public static final String STORAGE_PATH = "tmp/";
    
    private static boolean debugMode = false;
    private static VSIGFrame frame = null;
    private static Simulation sim = null;
    private static Profile profile = Profile.getDefault();
}

